package com.gzsxy.esjy.handler;


import com.gzsxy.esjy.request.HttpServletRequest;
import com.gzsxy.esjy.request.impl.BaseRequest;
import com.gzsxy.esjy.response.NettyHttpResponse;
import com.gzsxy.esjy.thread.ExcuteService;
import com.gzsxy.esjy.thread.NettyServicePool;
import com.gzsxy.esjy.thread.ServiceRunnable;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;

/**
 * http处理（最后执行）
 *
 * @author zhangxiaolong
 * @date 2022/7/6 9:36
 */
public class HttpHandler extends BaseHandler<HttpServletRequest> {

	private final NettyServicePool pool ;
	
	private final ExcuteService excuteService;
	
	private final boolean threadEnabled;
	
	public HttpHandler(NettyServicePool pool, ExcuteService excuteService, boolean threadEnabled) {
		super();
		this.pool = pool;
		this.excuteService = excuteService;
		this.threadEnabled = threadEnabled;
	}

	/**
	 * 监听读事件
	 * @param context
	 * @param request
	 * @throws Exception
	 */
	@Override
	protected void channelRead0(ChannelHandlerContext context, HttpServletRequest request) throws Exception {
		BaseRequest base = ((BaseRequest)request);
		try {
			//请求是否解析成功
			if(request.getDecoderResult().isSuccess()) {
				ServiceRunnable serviceRunnable = new ServiceRunnable(excuteService, request, context);
				//启动异步线程
				if(threadEnabled) {
					pool.start(serviceRunnable);
				}else {
					serviceRunnable.run();
				}
			}else {
				//响应解析失败
				ChannelFuture writeAndFlush = context.writeAndFlush(NettyHttpResponse.createError(new RuntimeException("报文解析异常"), request.getCharset().name()));
				if(!base.isKeepAlive()) {
					writeAndFlush.addListener(ChannelFutureListener.CLOSE);
				}
			}
		} catch (Exception e) {
			//响应异常失败
			ChannelFuture writeAndFlush = context.writeAndFlush(NettyHttpResponse.doExceptionResponse(e, request.getCharset().name()));
			if(!base.isKeepAlive()) {
				writeAndFlush.addListener(ChannelFutureListener.CLOSE);
			}
		}
		
	}
	
	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		ctx.fireChannelInactive();

	}
	@Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
		ChannelFuture writeAndFlush = ctx.writeAndFlush(NettyHttpResponse.doExceptionResponse(cause, "utf-8"));
		writeAndFlush.addListener(ChannelFutureListener.CLOSE);
    }

	@Override
	public Object getContent() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void setContent(Object content) {
		// TODO Auto-generated method stub
		
	}
}
